﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Linq;
using System.Net;
using System.Resources;
using System.Threading;
using System.Threading.Tasks;
using DownloadFiles.Properties;

namespace DownloadFiles
{
    public partial class MainForm : Form
    {
        DataTable dt = new DataTable();
        const int MAX_TASK = 5;
        private object lockObject = new object();
        private bool CheckFileExist = true;

        private void AddColumn(DataColumn dataColumn, bool hide = false, int? width = null)
        {
            dt.Columns.Add(dataColumn);
            var col = new DataGridViewTextBoxColumn()
            {
                HeaderText = dataColumn.Caption,
                DataPropertyName = dataColumn.ColumnName,
                MinimumWidth = 60,
                Width = width.GetValueOrDefault(0),

            };
            if (width.HasValue)
            {
                col.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            }
            dataGridView.Columns.Add(col);
        }

        void Init()
        {

            AddColumn(new DataColumn("Id")
            {
                Caption = "编号",
                DataType = typeof(int),
                AutoIncrement = true,
                AutoIncrementSeed = 1,
                AllowDBNull = false,
                AutoIncrementStep = 1,
            }, width: 100);

            AddColumn(new DataColumn("Url")
            {
                Caption = "待下载文件",
                AllowDBNull = false,
                DataType = typeof(string)
            });
            AddColumn(new DataColumn("SavePath")
            {
                Caption = "文件保存路径",
                AllowDBNull = false,
                DataType = typeof(string)
            });
            dt.Columns.Add(new DataColumn("StateId")
            {
                DataType = typeof(int),
                DefaultValue = 0,
                AllowDBNull = false,
            });
            AddColumn(new DataColumn("State")
            {
                Caption = "下载状态",
                AllowDBNull = false,
                DataType = typeof(string)
            }, width: 100);
            //dt.Rows.Add(null, "test", "", "");
            //dt.Rows.Add(null, "2", "", "");
            //dt.Rows.Add(null, "3", "", "");
            dataGridView.AutoGenerateColumns = false;
            dataGridView.AutoSize = true;
            dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
            dataGridView.DataSource = dt;

            //row.SetField("","");
        }


        public MainForm()
        {
            InitializeComponent();
            Init();
        }

        private void ToolStripMenuItem_CDN_Click(object sender, EventArgs e)
        {
            var form = new AddFileForm_CDN();
            form.AddFileCallback = (files) =>
            {
                foreach (var keyValuePair in files)
                {
                    if (dt.Select(string.Format("SavePath='{0}'", keyValuePair.Value)).Any())
                    {
                        continue;
                    }
                    dt.Rows.Add(null, keyValuePair.Key, keyValuePair.Value, 0, "");
                }
            };
            form.ShowDialog();
        }

        private void aboutToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            var form = new AboutBox();

            form.ShowDialog();
        }

        private int downloadState = 0;
        CancellationTokenSource cancellationTokenSource;
        private void Download()
        {
            while (downloadState == 1)
            {
                if (cancellationTokenSource.IsCancellationRequested)
                {
                    break;
                }
                var data = dt.Select("StateId=0");
                if (!data.Any())
                {
                    // startDownloadToolStripMenuItem.Enabled = true;
                    downloadState = 3;
                    break;
                }

                Parallel.ForEach(data.Take(MAX_TASK), (row, parallelLoopState) =>
                {
                    if (cancellationTokenSource.IsCancellationRequested)
                    {
                        parallelLoopState.Stop();
                        return;
                    }
                    var stateId = 1;
                    string state = "正在下载";
                    var path = row.Field<string>("SavePath");

                    if (CheckFileExist && File.Exists(path))
                    {
                        state = "文件已存在";
                        stateId = 3;
                        lock (lockObject)
                        {
                            row.SetField("StateId", stateId);
                            row.SetField("State", state);
                        }
                        return;
                    }

                    lock (lockObject)
                    {
                        row.SetField("StateId", stateId);
                        row.SetField("State", state);
                    }
                    var dir = Path.GetDirectoryName(path);
                    if (!Directory.Exists(dir))
                    {
                        Directory.CreateDirectory(dir);
                    }
                    try
                    {
                        using (var webClient = new WebClient())
                        {
                            webClient.DownloadFile(row.Field<string>("Url"), path);
                        }
                        state = "下载完成";
                        stateId = 3;
                    }
                    catch (Exception e)
                    {
                        state = e.Message;
                        stateId = 2;
                    }
                    lock (lockObject)
                    {
                        row.SetField("StateId", stateId);
                        row.SetField("State", state);
                    }
                });
            }
        }


        //private Thread downloadThread;
        private Task downloadTask;
        private void startDownloadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            downloadState = 1;
            startDownloadToolStripMenuItem.Enabled = false;
            cancellationTokenSource = new CancellationTokenSource();
            // downloadThread = new Thread(Download);
            // downloadThread.Start();
            downloadTask = Task.Factory.StartNew(Download).ContinueWith((task) =>
             {
                 startDownloadToolStripMenuItem.Enabled = true;
             });
        }

        private void pauseDownloadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            downloadState = 2;
            startDownloadToolStripMenuItem.Enabled = true;
            // downloadThread.Abort();
            // downloadTask.
            cancellationTokenSource.Cancel();
        }

        protected override void OnClosed(EventArgs e)
        {
            base.OnClosed(e);
            try
            {
                if (dt == null || dt.Rows.Count == 0 || !dt.Select("StateId<>3").Any())
                {
                    return;
                }
                var pathDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "log");
                if (!Directory.Exists(pathDir))
                {
                    Directory.CreateDirectory(pathDir);
                }
                CommFunc.SaveTmpData(dt, Path.Combine(pathDir, "DownloadFiles_" + DateTime.Now.ToString("yyyyMMddHHmmssfffff") + ".tmpData"));
            }
            catch (Exception ex)
            {
            }
        }

        private void resetFailToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (var dataRow in dt.Select(string.Format("StateId={0}", 2)))
            {
                dataRow.SetField("StateId", 0);
                dataRow.SetField("State", "状态已重置");
            }
        }

        private void saveTmpDateToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (saveFileDialog_TmpData.ShowDialog() == DialogResult.OK)
            {
                CommFunc.SaveTmpData(dt, saveFileDialog_TmpData.FileName);
            }
        }

        private void loadTmpDataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (openFileDialog_LoadTmpData.ShowDialog() == DialogResult.OK)
            {
                var tmpDt = CommFunc.LoadTmpData(openFileDialog_LoadTmpData.FileName);
                if (tmpDt == null)
                {
                    MessageBox.Show("加载数据失败，请确认文件！");
                    return;
                }
                foreach (DataRow row in tmpDt.Rows)
                {
                    dt.ImportRow(row);
                }
                MessageBox.Show("数据加载完成！");
            }
        }
    }

}
